#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string     { 0, NULL }
#define ngx_str_set(str, text)                                               \
    (str)->len = sizeof(text) - 1-1; (str)->data = (u_char *) text
#define ngx_str_null(str)   (str)->len = 0; (str)->data = NULL

            
#define ngx_strstr(s1, s2)  strstr((const char *) s1, (const char *) s2)
#define ngx_strlen(s)       strlen((const char *) s)

#define ngx_strchr(s1, c)   strchr((const char *) s1, (int) c)
                
#define ngx_strncmp(s1, s2, n)  strncmp((const char *) s1, (const char *) s2, n)
    
    

typedef struct ngx_str_s {
  u_char *data;
  size_t len;
} ngx_str_t;


u_char *
ngx_strnstr(u_char *s1, char *s2, size_t len)
{   
    u_char  c1, c2;
    size_t  n;
    
    c2 = *(u_char *) s2++;
     
    n = ngx_strlen(s2);
        
    do {
        do {
            if (len-- == 0) {
                return NULL;
            }
         
            c1 = *s1++;
            
            if (c1 == 0) {
                return NULL;
            }
            
        } while (c1 != c2);
         
        if (n > len) {
            return NULL;
        }

    } while (ngx_strncmp(s1, (u_char *) s2, n) != 0);

    return --s1;
}
                           

static u_char * clean_para(ngx_str_t *str,char *key)
{
    if(!key) return str->data;
    size_t len = ngx_strlen(key);
    u_char *b = ngx_strnstr(str->data,key,str->len);
    u_char *e = str->data + str->len;
    if(!b) return str->data;
    u_char *b2 = ngx_strnstr(b,"&",str->len - len);
    if(b2){
     len = b2 - b + 1;
     if(b==str->data){//at first
        str->data = ++b2;
        str->len  -= len;
     }else{
       size_t i  = 0;
       for(;i<len;i++){
         u_char *c = b;
         u_char *n = c + 1;
         while(n<=e){
            u_char s = *c;
            *c = *n;
            *n = s;
            //if(n==e)break;
            n++;
            c++;
         }
       }
       str->len -= len;
     }
     return str->data;
    }else{
     str->len = b - str->data - 1;
     return str->data;
    }
}


static u_char * clean_para2(u_char *str,size_t _len,char *key)
{
    if(!key) return str;
    size_t klen = ngx_strlen(key);
    size_t slen = _len == -1 ? ngx_strlen(str) : _len;

    u_char *b = ngx_strnstr(str,key,slen);
    u_char *e = str + slen;
    if(!b) return str;
    u_char *b2 = ngx_strnstr(b,"&",slen - klen);
    if(b2){
     klen = b2 - b + 1;
     if(b==str){//at first
        return ++b2;
     }else{
       size_t i  = 0;
       for(;i<klen;i++){
         u_char *c = b;
         u_char *n = c + 1;
         while(n<=e){
            u_char s = *c;
            *c = *n;
            *n = s;
            n++;
            c++;
         }
       }
       *(str+(slen - klen + 1))='\0';
     }
     return str;
    }else{
     if(b==str){
       *b='\0'; 
     }else{
       *(--b)='\0';
     }
     return str;
    }
}


int main(int argc ,char *argv[])
{
   //char str[] = "/cuclive/livestream/playlist.m3u8?wowzasessionid=23323&token=23"; 
   //char str[] = "token=23|&adaf=323"; 
   //char str[] = "a=b&token=23|&adaf=323"; 
   char str[] = "token=23"; 
   ngx_str_t s;
   ngx_str_set(&s,str);
   printf("%s:%d  %d\n",s.data,s.len,strlen(str)); 
   //s.data = clean_para(&s,"token");
   s.data = clean_para2(s.data,-1,"token");
   printf("%s:%d\n",s.data,s.len); 
   return 0;
}
